import { ReportType } from './constant';
import { ReportParams } from './types';
import Utils from './utils';
import { record, pack } from 'rrweb';

/**
 * 用户行为录制
 */
export default class BehaviorRecorder {
	private instanceRecord: any;
	private events: any = [];
	private isRecording = false;
	constructor(private callback: (params: ReportParams) => void) {
		Utils.log('用户行为录制初始化成功');
	}
	public start(): void {
		if (this.isRecording) return;
		Utils.log('debug', '开始录制');
		this.isRecording = true;
		this.events = [];
		this.instanceRecord = record({
			emit: event => {
				this.events.push(event);
			},

			/**
			 * 性能优化：每N个事件后生成一个全量快照
			 * 防止增量事件过多导致内存问题
			 */
			checkoutEveryNth: 100,

			/**
			 * 性能优化：每N毫秒强制生成全量快照
			 * 防止长时间未生成快照导致重放问题
			 */
			checkoutEveryNms: 30 * 1000, // 30秒

			/**
			 * 降低鼠标移动事件采样率
			 * 平衡精度和性能（值越高采样率越低）
			 */
			mousemoveWait: 150,

			/**
			 * 安全：添加此类名的元素将被完全阻止录制
			 * 用法：<div class="rr-block">敏感内容</div>
			 */
			blockClass: 'rr-block',

			/**
			 * 安全：添加此类名的元素内容将被忽略
			 * 用法：<div class="rr-ignore">忽略内容但保留元素</div>
			 */
			ignoreClass: 'rr-ignore',

			/**
			 * 安全：添加此类名的文本内容将被掩码
			 * 用法：<span class="rr-mask">信用卡号</span>
			 */
			maskTextClass: 'rr-mask',

			/**
			 * 安全：自动掩码所有输入框内容
			 * 防止敏感数据泄露
			 */
			maskAllInputs: true,

			/**
			 * 安全：细化输入框掩码配置
			 */
			maskInputOptions: {
				password: true, // 密码框
				text: true, // 文本输入
				email: true, // 邮箱输入
				tel: true, // 电话输入
				number: true, // 数字输入
				search: true, // 搜索框
				url: true, // URL输入
				textarea: true, // 文本域
				select: true, // 下拉选择
			},

			/**
			 * 数据压缩：使用rrweb自带的LZ字符串压缩
			 * 可减少30-70%的数据体积
			 */
			packFn: pack,

			/**
			 * DOM优化：精简DOM结构
			 * 移除不必要的内容以减小数据大小
			 */
			slimDOMOptions: {
				script: true, // 移除脚本
				comment: true, // 移除注释
				headFavicon: true, // 移除favicon
				headWhitespace: true, // 移除头部空白
				headMetaSocial: true, // 移除社交媒体meta
			},

			/**
			 * 高级功能：录制Canvas内容
			 * 适用于图形验证码、图表等场景
			 */
			recordCanvas: false,

			/**
			 * 性能优化：内联样式表
			 * 提高重放准确性，但略微增加数据大小
			 */
			inlineStylesheet: true,

			/**
			 * 字体处理：收集页面字体
			 * 确保重放时字体一致性
			 */
			collectFonts: true,

			/**
			 * 跨域支持：录制跨域iframe内容
			 * 需要目标iframe配合设置allow-same-origin
			 */
			recordCrossOriginIframes: true,

			/**
			 * 采样策略：优化高频事件
			 */
			sampling: {
				scroll: 150, // 滚动事件采样间隔(ms)
				input: 'last' as const, // 只记录最终输入值

				// 鼠标交互事件采样
				mouseInteraction: {
					MouseUp: true,
					MouseDown: true,
					Click: true,
					ContextMenu: true,
					DblClick: true,
					Focus: true,
					Blur: true,
					TouchStart: true,
					TouchEnd: true,
				},
			},
		});
	}

	public stop(): Array<any> {
		Utils.log('debug', '终止录制');

		this.isRecording = false;
		this.callback({
			type: ReportType.BEHAVIOR_RECORDER,
			data: this.events,
		});
		this.instanceRecord && this.instanceRecord();
		return this.events;
	}
}
